package com.ufgov.pdf.util;

import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.ufgov.pdf.entity.Radio;
import com.ufgov.pdf.entity.Title;
import com.ufgov.pdf.entity.table.Table;
import com.ufgov.pdf.entity.table.Tablepage;
import com.ufgov.pdf.entity.table.Td;
import com.ufgov.pdf.entity.table.Tr;

/**
 * 导出pdf核心帮助类 xml与数据装配核心方法
 */
public class PdfHelper {

	/**
	 * xml与数据装配页面<br>
	 * 核心方法，负责输出文档 TODO:目前这个方法是把imgPath和tempPath当做参数传入，但是我觉得还是做成组件比较好。
	 * 
	 * @param filePath
	 *            xml模板全路径
	 * @param dataMap
	 *            数据源（目前只允许传Map<String, Object> 和List<Map<String, Object>>）
	 * @param out
	 *            输出流，可以是response，或者其它的流
	 * @throws Exception
	 */
	// HttpServletResponse response,
	@SuppressWarnings("unchecked")
	public static void convert(String filePath, Map<String, Object> dataMap, OutputStream out) throws Exception {
		try {
			// 解析模板
			Tablepage tablepage = JaxbUtil.converyToJavaBean(filePath, Tablepage.class);

			String fileName = tablepage.getFileName();
			if (StringUtil.isEmpty(fileName)) {
				fileName = (new SimpleDateFormat("yyyyMMddHHmmss").format(Calendar.getInstance().getTime())) + ".pdf";
				System.out.println("文件名为空,将使用默认文件名:" + fileName);
			}

			Rectangle rectPageSize = new Rectangle(PageSize.A4);
			Document document = new Document(rectPageSize, -30, -30, 30, 20);

			PdfWriter writer = PdfWriter.getInstance(document, out);
			document.open();

			List<Table> tableList = tablepage.getTableList();
			if (tableList == null || tableList.size() < 1) {
				return;
			}

			for (Table table : tableList) {
				// 添加横向支持
				document.setPageSize(table.getRotate().equals("true") ? rectPageSize.rotate() : rectPageSize);

				document.newPage();
				PdfPTable table1 = new PdfPTable(Integer.parseInt(table.getCols()));
				// table1.setLockedWidth(true);
				Title t = table.getTitle();
				PdfPTable tableTitle = new PdfPTable(1);
				if (t != null && t.getText() != null) {
					setTitle(document, t, tableTitle);
				}

				List<Tr> trList = table.getTrList();
				String entity = table.getEntity();
				if (trList == null || trList.size() < 1) {
					document.add(table1);
					continue;
				}
				for (int i = 0; i < trList.size(); i++) {
					Tr tr = trList.get(i);
					// 检测是否是list表格
					if (!StringUtil.isEmpty(tr.getForeach()) && tr.getForeach().equalsIgnoreCase("true")) {
						// 表格标题行
						if (i == 0) {
							renderTd(table1, tr, null);
							continue;
						}
						String trEntity = tr.getEntity();
						// 没有填充数据,不循环
						if (StringUtil.isEmpty(trEntity) || !dataMap.containsKey(trEntity)) {
							System.out.println("<tr>的entity设置不正确!");
							continue;
						}
						// 强制转换为List<Map<String,Object>>类型
						List<Map<String, Object>> dataList = (List<Map<String, Object>>) dataMap.get(trEntity);
						if (dataList == null || dataList.size() < 1) {
							System.out.println("<tr>的entity为空哟!");
							continue;
						}
						// 列表 序号列
						int idx = 1;
						for (Map<String, Object> en : dataList) {
							tr.setIndex(String.valueOf(idx++));
							renderTd(table1, tr, en);
						}
					} else if (StringUtil.isNotEmpty(tr.getEntity())) {// 处理合计行
						renderTd(table1, tr, (Map<String, Object>) dataMap.get(tr.getEntity()));
					} else {
						renderTd(table1, tr, (Map<String, Object>) dataMap.get(entity));
					}
				}
				document.add(table1);
			}
			document.close();
			writer.close();
			// }

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private static void renderTd(PdfPTable table1, Tr tr, Map<String, Object> obj)
			throws DocumentException, IOException {

		BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
		Font font = new Font(baseFont, 10, Font.NORMAL);

		// TODO:这个地方可以做成静态数据，也可以不做，只是为了输出的时候更简单
		Map<String, Integer> posMap = new HashMap<String, Integer>();
		posMap.put("center", Element.ALIGN_CENTER);
		posMap.put("left", Element.ALIGN_LEFT);
		posMap.put("right", Element.ALIGN_RIGHT);

		posMap.put("top", Element.ALIGN_TOP);
		posMap.put("middle", Element.ALIGN_MIDDLE);
		posMap.put("bottom", Element.ALIGN_BOTTOM);

		List<Td> tdList = tr.getTdList();
		if (tdList == null || tdList.size() < 1) {
			return;
		}
		for (Td td : tdList) {
			String text = td.getText();
			System.out.println(text);
			font = new Font(baseFont, 10, td.getWeight() != null ? Font.BOLD : Font.NORMAL);
			if (td.isIndex()) {// 序号列
				text = tr.getIndex();
			} else {
				if (text != null && text.contains("{{") && null != obj) {
					List<String> list = StringUtil.findStringForPDF(text);
					for (int i = 0; i < list.size(); i++) {
						String textOld = list.get(i);
						String key = list.get(i).replace("{{", "").replace("}}", "");
						String newVal = obj.containsKey(key) && obj.get(key) != null ? obj.get(key).toString() : "";
						text = text.replace(textOld, newVal);
					}
				}
			}

			//TODO:Radio和image在这里获取不合理，需要改正
			
			Radio radio = td.getRadio();
			if (radio != null) {
				//TODO:由于☑无法显示，因此，可能要使用图片来生成了。
				text = radio.isChecked() ? "√" : "□";
			}
			
			PdfPCell cell = new PdfPCell(new Paragraph(text, font));

			String borderWidth = td.getBorderWidth();
			float[] borderArr = getBorder(borderWidth);
			if (borderArr != null) {
				cell.setBorderWidthTop(borderArr[0]);
				cell.setBorderWidthRight(borderArr[1]);
				cell.setBorderWidthBottom(borderArr[2]);
				cell.setBorderWidthLeft(borderArr[3]);
			}
			com.ufgov.pdf.entity.Image image = td.getImage();
			if (image != null) {
				Image img = Image.getInstance(image.getSrc());
				cell.setImage(img);
			}

			cell.setColspan(Integer.parseInt(td.getColspan()));
			cell.setRowspan(Integer.parseInt(td.getRowspan()));
			cell.setHorizontalAlignment(posMap.get(td.getAlign()));
			cell.setVerticalAlignment(posMap.get(td.getvAlign()));
			cell.setMinimumHeight(20f);
			// if (arr[2] != 0) {
			// cell.setFixedHeight(20f);
			// }
			table1.addCell(cell);
		}
	}

	/**
	 * 在这里设置边框。暂时没有什么好的方法
	 */
	private static float[] getBorder(String borderWidth) {
		if (borderWidth == null) {
			return null;
		}
		float[] borderArr = new float[4];
		String[] borderWidths = borderWidth.split("\\s+");
		// 校验边框
		int borderNum = borderWidths.length;
		switch (borderNum) {
		case 1:
			float f = StringUtil.isEmpty(borderWidths[0]) ? 1f : Float.parseFloat(borderWidths[0]);
			borderArr = new float[] { f, f, f, f };
			break;
		case 2:
			borderArr[0] = Float.parseFloat(borderWidths[0]);
			borderArr[1] = borderArr[0];
			borderArr[2] = Float.parseFloat(borderWidths[1]);
			borderArr[3] = borderArr[2];
			break;
		case 3:
			borderArr[0] = Float.parseFloat(borderWidths[0]);
			borderArr[1] = Float.parseFloat(borderWidths[1]);
			borderArr[2] = Float.parseFloat(borderWidths[2]);
			borderArr[3] = 0;
			break;
		case 4:
			borderArr[0] = Float.parseFloat(borderWidths[0]);
			borderArr[1] = Float.parseFloat(borderWidths[1]);
			borderArr[2] = Float.parseFloat(borderWidths[2]);
			borderArr[3] = Float.parseFloat(borderWidths[3]);
			break;
		default:
			borderArr[0] = borderArr[1] = borderArr[2] = borderArr[3] = 1;
			break;
		}

		return borderArr;
	}

	private static void setTitle(Document document, Title title, PdfPTable tableTitle) throws Exception {
		PdfPCell cell = new PdfPCell(new Paragraph(title.getText(), new Font(
				BaseFont.createFont(title.getFontFamily(), "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 17, Font.NORMAL)));
		// TODO:这个地方要设置标题的位置,暂时先不写
		cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 设置单元格中文本位置（居中：ALIGN_CENTER；靠左：ALIGN_LEFT；靠右：ALIGN_RIGHT）
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 文本垂直方向位置（靠上：ALIGN_TOP；居中：ALIGN_MIDDLE；靠下：ALIGN_BOTTOM；）
		cell.setBorderWidth(0f); // 设置单元格边框，参数都为float
		cell.setPaddingBottom(20f); // 设置单元格文本内边距
		tableTitle.addCell(cell);

		document.add(tableTitle);
	}
}
